package srst.ai.gephi;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.gephi.graph.api.Edge;
import org.gephi.graph.api.Node;
import org.gephi.graph.api.UndirectedGraph;
import org.gephi.graph.impl.GraphModelImpl;

import srst.ai.gephi.Modularity;
import srst.util.FilePathUtil;
import srst.util.FileUtil;




/** 
* @author  作者 : YUHU YUAN
* @date 创建时间：2017年5月18日 下午8:46:18 
* @version 1.0  
*/

public class ModularityService {
	
	private Map<String, Integer> resumeName_ClassMap = new HashMap<>();
	private int classNum = 0 ;
	  
	/** 
	* @author  作者 : YUHU YUAN
	* @date 创建时间：2017年5月18日 下午8:50:37 
	* @parameter resumeMap<resumeName, text>
	* @return
	* @throws
	*/
	public void computeUndirectedGraphModularity(List<String> graphInfo,Map<String, String> resumeMap) {
	    GraphModelImpl graphModel = new GraphModelImpl();
        UndirectedGraph undirectedGraph = graphModel.getUndirectedGraph();
        Map<String, Node> resumeName_NodeMap = new HashMap<>();
        //构建节点
        Node node = null;
        for(String resumeName : resumeMap.keySet()){
        	node = graphModel.factory().newNode(resumeName);
        	undirectedGraph.addNode(node);
        	resumeName_NodeMap.put(resumeName, node);
        	resumeName_ClassMap.put(resumeName, -1);
        }
        
        //构建边
        Edge edge = null;
        for(String info : graphInfo){
        	System.out.println(info);
        	String[] infos = info.split("\t");
        	edge = graphModel.factory().newEdge(resumeName_NodeMap.get(infos[0]), resumeName_NodeMap.get(infos[1]), 0, Double.valueOf(infos[2]), false);
        	undirectedGraph.addEdge(edge);
        }

      
        Modularity mod = new Modularity();

        Modularity.CommunityStructure theStructure = mod.new CommunityStructure(undirectedGraph);
        
        int[] comStructure = new int[undirectedGraph.getNodeCount()];

        HashMap<String, Double> modularityValues = mod.computeModularity(undirectedGraph, theStructure, comStructure,
                1., true, true);
        
        for(String string: modularityValues.keySet()){
        	System.out.println(string+" ： "+modularityValues.get(string));
        }
        
        for(int i : comStructure){
        	System.out.println(i);
        }
        
        Set<Integer> countClassNum = new HashSet<>(); 
        int count = 0;
        for (String resumeName : resumeName_ClassMap.keySet()){
        	resumeName_ClassMap.put(resumeName, comStructure[count]);
        	countClassNum.add(comStructure[count]);
        	count++;
        }  
        
        classNum = countClassNum.size();
        
        System.out.println("===============模块划分结果");

       for(String resumeName : resumeName_ClassMap.keySet()){
    	   System.out.println(resumeName  +" : "+resumeName_ClassMap.get(resumeName));
       }
       
	}
	
	
	/** 
	* @author  作者 : YUHU YUAN
	* @date 创建时间：2017年5月18日 下午10:16:18 
	* @parameter 
	* @return
	* @throws
	* 确定最终的类别的归属
	* 
	*/
	private List<String> getSignResume(String inputPath){
		File resumeFolder = new File(inputPath);
		File[] fileArray = resumeFolder.listFiles();
		
		List<String> signNameList = new ArrayList<>();
		for(File resume : fileArray){
			String resumeName = resume.getName();
			resumeName = resumeName.substring(0, resumeName.indexOf("."));
			signNameList.add(resumeName);
		}
		return signNameList;
	}
	
	
	public void resultHandle() throws IOException{
		Map<String, File> fileMap = FileUtil.getFileMap(FilePathUtil.RESUME_PATH);
		Map<Integer, List<String>> class_nodeListMap = new HashMap<>();
		int[] classNums = new int[classNum];
		List<String>  signFileName = getSignResume(FilePathUtil.SIGN_PATH);
		if(classNum != 1){
			//这里完成两个功能，一：把某个类别的文件合并到list中，二：统计每个类别中标签的个数
			for(String resumeName : resumeName_ClassMap.keySet()){
				int classNode = resumeName_ClassMap.get(resumeName);
				if(!signFileName.contains(resumeName)){
					List<String> resumes = null;
					if(class_nodeListMap.containsKey(classNode)){
						resumes =  class_nodeListMap.get(classNode);
						resumes.add(resumeName);
						class_nodeListMap.put(classNode, resumes);
					}else{
						resumes =  new ArrayList<>();
						resumes.add(resumeName);
						class_nodeListMap.put(classNode, resumes);
					}
				}else{
					classNums[classNode]++;
				}
			}
		}
		
		
		if(classNum == 1){
			createDir(classNum);
			String path = FilePathUtil.MODULE_PARTITION_RESULT_PATH+File.separator+"十分符合"+File.separator;
			movefile(path,fileMap.values());
		}else if(classNum == 2){
			createDir(classNum);
			int flag = (classNums[0] > classNums[1] ? 0:1);
			String firstPath = FilePathUtil.MODULE_PARTITION_RESULT_PATH+File.separator+"十分符合"+File.separator;
			String secondPath = FilePathUtil.MODULE_PARTITION_RESULT_PATH+File.separator+"符合"+File.separator;
			List<String> firstFileNames = class_nodeListMap.get(flag);
			movefile(firstPath, firstFileNames, fileMap);
			flag = (flag==0? 1 : 0);
			List<String> secondFileNames = class_nodeListMap.get(flag);
			movefile(secondPath, secondFileNames, fileMap);
		}else {
			createDir(classNum);
			//控制创建一个文件夹还是两个文件夹
			boolean flag = false;
			String secondPath = FilePathUtil.MODULE_PARTITION_RESULT_PATH+File.separator+"符合"+File.separator;
			String thirdPath = FilePathUtil.MODULE_PARTITION_RESULT_PATH+File.separator+"不符合"+File.separator;
			int maxNumClass = 0;
			int locat = 0;
			for(int i=0; i<2; i++){
				for(int j=0; j<classNums.length; ++j){
					if(classNums[j]>maxNumClass){
						maxNumClass = classNums[j];
						locat = j;
					}	
				}
				List<String> fileNames = null;
				if(i==0){
					fileNames = class_nodeListMap.get(locat);
					String firstPath = FilePathUtil.MODULE_PARTITION_RESULT_PATH+File.separator+"十分符合"+File.separator;
					movefile(firstPath, fileNames, fileMap);
					locat = 0;
					classNums[locat] =0;
					maxNumClass = 0;
					class_nodeListMap.remove(locat);
					continue;
				}
				if(maxNumClass == 0){
					flag = true;
					break;
				}
				fileNames = class_nodeListMap.get(locat);
				movefile(secondPath, fileNames, fileMap);
				class_nodeListMap.remove(locat);
			}
			String path = null;
			if(flag == true){
				path = secondPath;
			}else{
				path = thirdPath;
			}
			List<String> fileNames = new ArrayList<>();
			for(int i : class_nodeListMap.keySet()){
				fileNames.addAll(class_nodeListMap.get(i));
			}
			movefile(path, fileNames, fileMap);
			
		}
	}
	
	private void createDir(int classNum){
		if(classNum>3){
			classNum =3;
		}
		String[] dirName = {"十分符合", "符合", "不符合"};
		File file = null;
		for(int i=0; i<classNum; i++){
			file = new File(FilePathUtil.MODULE_PARTITION_RESULT_PATH+File.separator+dirName[i]);
			file.mkdir();
		} 
	}
	
	private void movefile(String path,Collection<File> files){
		for(File srcFile : files){
			String fileName = srcFile.getName();
			File distFile = new File(path+fileName);
			srcFile.renameTo(distFile);
		}
	}
	
	private void movefile(String path,List<String> fileNames,Map<String, File> fileMap){
		for(String fileName : fileNames){
			File srcFile = fileMap.get(fileName);
			String name = srcFile.getName();
			File distFile = new File(path+name);
			srcFile.renameTo(distFile);
		}
	}
	
	
//	public  void main(String[] args) throws IOException{
//		ModularityService modularityService = new ModularityService();
//		modularityService.resultHandle();
//		
//		
//	}
	
	
	
	

}



















